package hos.okhttp.utils;

import java.io.File;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import hos.http.HttpBaseRequest;
import hos.http.HttpBaseRequestBody;
import hos.http.HttpBaseRequestDownload;
import hos.http.HttpBaseRequestSoap;
import hos.http.HttpFile;
import hos.http.HttpParam;
import hos.http.HttpTag;
import hos.http.HttpUtils;
import hos.okhttp.http.FileRequestBody;
import hos.okhttp.http.OkHttpInterceptor;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * <p>Title: OkHttpUtils </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-03-25 19:28
 */
public class OkHttpUtils {

    public static OkHttpClient buildOkhttp(final OkHttpClient okHttpClient, HttpBaseRequest<?> request) {
        List<Interceptor> interceptors = okHttpClient.interceptors();
        OkHttpClient.Builder builder = okHttpClient.newBuilder()
                .connectTimeout(request.getConnectTimeout(), TimeUnit.SECONDS)
                .readTimeout(request.getReadTimeout(), TimeUnit.SECONDS)
                .writeTimeout(request.getWriteTimeout(), TimeUnit.SECONDS)
                .retryOnConnectionFailure(false);
        boolean isSoapInterceptor = false;
        for (Interceptor interceptor : interceptors) {
            if (interceptor instanceof OkHttpInterceptor) {
                isSoapInterceptor = true;
                break;
            }
        }
        if (!isSoapInterceptor) {
            builder.addInterceptor(new OkHttpInterceptor(request.getRetryCount()));
        }
        return builder.build();
    }

    /**
     * 处理请求头部
     *
     * @param request 请求
     */
    public static Headers.Builder buildRequestHeader(HttpBaseRequest<?> request) {
        Map<String, String> header = request.getHeader();
        Headers.Builder builder = new Headers.Builder();
        if (!header.isEmpty()) {
            Set<String> headerKeys = header.keySet();
            for (String headerKey : headerKeys) {
                String value = header.get(headerKey);
                if (value != null && value.length() != 0) {
                    builder.add(headerKey, value);
                } else {
                    builder.add(headerKey, "");
                }
            }
        }
        return builder;
    }

    /**
     * 处理请求体
     *
     * @param request 请求
     */
    public static RequestBody buildRequestBody(HttpBaseRequest<?> request) {
        List<HttpParam> params = new LinkedList<>();
//        List<HttpParam> queryParameters = request.getQueryParameters();
//        if (queryParameters != null) {
//            params.addAll(queryParameters);
//        }
        List<HttpParam> bodyParameters = request.getBodyParameters();
        if (bodyParameters != null) {
            params.addAll(bodyParameters);
        }
        String type = request.getContentType();
        MediaType contentType = MediaType.parse(type);
        if (request instanceof HttpBaseRequestSoap<?>) {
            HttpBaseRequestSoap<?> requestSoap = (HttpBaseRequestSoap<?>) request;
            return RequestBody.create(requestSoap.getDataXml().getBytes(), contentType);
        }
        if (request instanceof HttpBaseRequestDownload<?>) {
            String bodyString = HttpUtils.urlParam(params);
            return RequestBody.create(bodyString, contentType);
        }
        if (request instanceof HttpBaseRequestBody<?>) {
            HttpBaseRequestBody<?> httpRequestBody = (HttpBaseRequestBody<?>) request;
            Object data = httpRequestBody.getData();
            List<HttpFile> fileList = httpRequestBody.getFileList();
            if (fileList != null && !fileList.isEmpty()) {
                MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
                multipartBuilder.setType(MultipartBody.FORM);
                // 添加附件
                for (HttpFile httpFile : fileList) {
                    File file = httpFile.getFile();
                    RequestBody fileBody = new FileRequestBody(file);
                    multipartBuilder.addFormDataPart(httpFile.getKey(), httpFile.getFileName(),
                            fileBody);
                }
                // 添加参数
                builderMultipartBody(params, multipartBuilder);
                return multipartBuilder.build();
            }
            if (data != null) {
                if (data instanceof byte[]) {
                    return RequestBody.create((byte[]) data, contentType);
                }
                return RequestBody.create((String) data, contentType);
            }
            boolean isMultipart = httpRequestBody.isMultipart();
            boolean isFormEncoded = httpRequestBody.isFormEncoded();
            if (isFormEncoded) {
                FormBody.Builder formBuilder = new FormBody.Builder();
                builderFormBody(params, formBuilder);
                return formBuilder.build();
            }
            if (isMultipart) {
                MultipartBody.Builder multipartBuilder = new MultipartBody.Builder();
                multipartBuilder.setType(MultipartBody.FORM);
                builderMultipartBody(params, multipartBuilder);
                return multipartBuilder.build();
            }
            String bodyString = HttpUtils.urlParam(params);
            return RequestBody.create(bodyString, contentType);
//            // 添加上传监听
//            if (httpRequestBody.uploadProgressListeners() != null && !httpRequestBody.uploadProgressListeners().isEmpty()) {
//                requestBody = new ProgressRequestBody(httpRequestBody.uploadProgressListeners(), requestBody);
//            }
        }
        // Get
        String bodyString = HttpUtils.urlParam(request.getBodyParameters());
        return RequestBody.create(bodyString, contentType);
    }

    private static void builderFormBody(List<HttpParam> params, FormBody.Builder formBuilder) {
        // 添加参数
        for (HttpParam param : params) {
            String key = param.getKey();
            Object value = param.getValue();
            boolean isEncoded = param.isEncoded();
            if (value == null) {
                formBuilder.add(key, "");
                continue;
            }
            if (value instanceof String) {
                if (((String) value).length() == 0 || "null".equalsIgnoreCase((String) value)) {
                    formBuilder.add(key, "");
                } else {
                    if (isEncoded) {
                        formBuilder.addEncoded(key, String.valueOf(value));
                    } else {
                        formBuilder.add(key, String.valueOf(value));
                    }
                }
            } else {
                formBuilder.add(key, String.valueOf(value));
            }
        }
    }

    private static void builderMultipartBody(List<HttpParam> params, MultipartBody.Builder multipartBuilder) {
        for (HttpParam param : params) {
            String key = param.getKey();
            Object value = param.getValue();
            if (value == null) {
                multipartBuilder.addFormDataPart(key, "");
                continue;
            }
            if (value instanceof String) {
                if (((String) value).length() == 0 || "null".equalsIgnoreCase((String) value)) {
                    multipartBuilder.addFormDataPart(key, "");
                } else {
                    multipartBuilder.addFormDataPart(key, String.valueOf(value));
                }
            } else if (value instanceof byte[]) {
                multipartBuilder.addFormDataPart(key, null,
                        RequestBody.create((byte[]) value, null));
            } else {
                multipartBuilder.addFormDataPart(key, String.valueOf(value));
            }
        }
    }

    public static Request.Builder buildRequest(HttpBaseRequest<?> request,
                                               String url,
                                               Headers headers,
                                               RequestBody requestBody) {
        if (!(request instanceof HttpBaseRequestSoap<?>)) {
            String query = HttpUtils.urlParam(request.getQueryParameters());
            if (query.length() != 0) {
                url += "?" + query;
            }
        }
        // 创建请求
        Request.Builder builder = new Request.Builder();
        builder.tag(HttpTag.DownloadListeners.class, request.downloadProgressListeners())
                .tag(HttpTag.UrlAndBody.class, new HttpTag.UrlAndBody(request))
                .method(request.getMethod(), request.isGet() ? null : requestBody)
                .headers(headers)
                .url(url);
        if (request instanceof HttpBaseRequestBody<?>) {
            builder.tag(HttpTag.UploadListeners.class, ((HttpBaseRequestBody<?>) request).uploadProgressListeners());
        }
        if (request instanceof HttpBaseRequestSoap<?>) {
            builder.tag(HttpTag.Soap.class, ((HttpBaseRequestSoap<?>) request).getSoapTag());
        }
        return builder;
    }
}
